在昨天的總結,其實就可以是今天的前言了。當我們需要建立多個互相溝通的容器時,靠指令一個一個慢慢打,還要注意彼此的啟動順序,一來一往,出錯機率大幅提升。
利用 Docker Compose 可以讓我們省去輸入一堆指令的麻煩,用一個檔案就能代替一堆指令。
先讓大家看過,Docker Compse 長什麼樣子,這樣介紹起來,會比較有概念。
Docker Compose 基本上跟 Dockerfile 一樣都是 yaml 檔:
version: '3.8'
services:
  rails:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    networks:
      - net
    depends_on:
      - postgres
  postgres:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
     - 5432:5432
    networks:
      - net
    environment:
      - POSTGRES_DB=Foo_production
      - POSTGRES_USER=Foo
      - POSTGRES_PASSWORD=Foobar
volumes:
  postgres_data:
networks:
  net:
當我們定義好 docker-compose.yml 後,我們就可以透過 docker-compose.yml 開始建立並運作所有的容器。
透過 docker-compose up 來執行,一鍵完成所有容器的建立!
這樣就省去了我們在前言提到的,再靠 docker 指令一個一個慢慢輸入的問題。
也可以加上 -d 在背景處理,這樣就不會在終端機上運作了。
執行完畢後,可以使用 docker-compose ps 來查看透過 docker-compose 所建立並在運作中的容器們。
如果想要增加某個 service 的容器數量時,可以使用 --scale 選項,後面則指定哪個 service、多少數量: docker-compose up --scale postgres=5
docker-compose 指令會透過 Docker Compose Yaml 檔案的內容,向 Docker API 發送指令,再由 Docker API,把指令內容傳遞給 Docker 應用程式。Docker 屬於容器工具,負責容器本身的生命週期,所以 Docker 本身並不負責 Docker Compose,簡單來說,他認不得 Docker Compose 的內容,所以需要透過 docker-compose 把內容告訴 Docker,讓 Docker 聽命行事。
Docker 會分配 IP 位置給容器,透過 IP 來發送請求,讓容器之間可以互相溝通。Docker 透過 DNS 服務器,讓 Docker 可以在不知道容器內部的 IP 的情況下,透過網域名稱找到相對應的容器,而這裡的網域名稱,就是容器的名稱。
那接著我們要透過上面的範例來講解在 docker-compose.yml 裡的指令。
services 主要是定義欲運行的容器,從上面範例中擷取部分來說明:
Services:
  rails:
  postgres:
這是在定義會有兩個容器,分別為 rails 跟 postgres,名字隨便你取,主要是要能一看就知道有什麼樣的容器,在這邊也可以取為 web_app 跟 database,都是可以的。
他們的位階跟 Services 是一樣的:
services:
  - app
volumes:
  - postgres_data
networks:
 - net
在 services 中,我們給各個容器設定了 volumes 跟 networks,都是要在外面 (也就是如上範例所示的第一位階處) 來設定,詳細的設定方式,有興趣可以 google 一下。
在 docker-compose.yml 中,若 volume 或 networks 設有 external ,則代表是要由外部預先建立好的 volume 或 networks 來提供 Compose 的 services 使用,而該 volume 或 networks 就不受 docker-compose 所管理,故在使用 docker-compose down 刪除容器時,並不會刪除設有 external 的 volume 或 networks。
services:
  # ...
networks:
  network1:
    name: my-pre-existing-network
    external: true
今天先把 Docker Compose 的基本概念與最上層的指令講接一次,接著明天,我們會繼續講解更細部的指令。